#include "TcpClient.hpp"
#include "Protocol.hpp"

using namespace TcpClientArea;

// void ClientQuit(int signo)
// {
//     (void)signo;
//     std::string message = "quit";
//     int n = ::send(sockfd, message.c_str(), message.size(), 0);
//     if (n < 0)
//     {
//         LOG(LogLevel::ERROR) << "send error";
//         DIE(SEND_ERR);
//     }

//     exit(0);
// }

//./TcoClient <server_ip> <server_port>
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        std::cout << "Usage: " << argv[0] << " <server_ip> <server_port>" << std::endl;
        return 1;
    }

    // ::signal(2, ClientQuit);

    std::string server_ip = argv[1];
    uint16_t server_port = std::stoi(argv[2]);

    // 创建套接字
    int sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        LOG(LogLevel::FATALER) << "socket error";
        DIE(SOCKET_ERR);
    }

    // 填充信息
    struct sockaddr_in server;
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = ::htons(server_port);
    server.sin_addr.s_addr = ::inet_addr(server_ip.c_str());

    // 链接
    int n = ::connect(sockfd, CONV(&server), sizeof(server));
    if (n < 0)
    {
        LOG(LogLevel::FATALER) << "connect error";
        DIE(CONNECT_ERR);
    }

    std::string message;
    while (true)
    {
        int x, y;
        char oper;
        std::cout << "Please set x: ";
        std::cin >> x;

        std::cout << "Please set y: ";
        std::cin >> y;

        std::cout << "Please set oper: ";
        std::cin >> oper;

        // 创建 Request 对象
        Request req(x, y, oper);

        // 序列化
        req.Serialize(message);//{json}

        // 打包, "len\r\{json}}\r\n" 格式
        Encode(message);

        // std::cout<<"Please Enter: ";
        // std::string message;
        // std::getline(std::cin,message);

        // 向服务器写消息
        int n = ::send(sockfd, message.c_str(), message.size(), 0);
        if (n > 0)
        {
            char buffer[1024];
            int m = ::recv(sockfd, buffer, sizeof(buffer) - 1, 0);
            buffer[m] = 0;
            LOG(LogLevel::DEBUG)<<buffer;
            if (m > 0)
            {
                buffer[m] = 0;
                LOG(LogLevel::DEBUG)<<"测试: "<<buffer;
                //获取客户端序列化+封装后的结果
                std::string package = buffer;

                //拿取其中{json}内容
                std::string content;
                Decode(package,&content);
                LOG(LogLevel::DEBUG)<<"content: "<<content;

                //反序列化,获取 result code
                Response res;
                res.Deserialize(content);

                //得到结构化的数据
                std::cout << res.Result() << "[" << res.Code() << "]" << std::endl;
            }
            else
                break;
        }
        else
            break;
    }

    ::close(sockfd);
    return 0;
}